<template>
  <!-- 标题 -->
  <div class="wave-wrap">
    <div class="header flex h-fit w-full justify-center">
      <div v-if="structureName" class="item">
        <span>测点名称</span>
        <span>{{ structureName }}</span>
      </div>
      <div class="item">
        <span>设备标识</span>
        <span>{{ stationId }}</span>
      </div>
      <div class="item">
        <span>采样率</span>
        <span>{{ samplingRate }}</span>
      </div>
      <div class="item">
        <span>烈度</span>
        <span>{{ intensity }}</span>
      </div>
      <div class="item">
        <span>数据延迟</span>
        <span class="w-10">{{ dataDelay }}</span>
      </div>
    </div>
    <!-- 波形图 -->
    <div class="flex-1/2 relative w-full overflow-hidden">
      <div :id="uuid" class="wave_pic h-full w-full"></div>
      <div
        v-if="!hasData"
        class="absolute left-0 top-0 flex h-full w-full items-center justify-center"
      >
        暂无数据
      </div>
    </div>
  </div>
</template>

<script setup lang="tsx">
import {
  computed,
  nextTick,
  onMounted,
  onUnmounted,
  ref,
  toRaw,
  useId,
  watch,
} from 'vue';
import { useEventSource } from '@boeyo/hooks';
import { useUserStore } from '@boeyo/portal';
import { realDataChart } from '@/utils/index';

const props = defineProps({
  stationId: {
    type: String,
    default: '',
  },
  style: {
    type: Object,
    default: () => ({}),
  },
  structureName: {
    type: String,
    default: '',
  },
});

const uuid = useId();

const hasData = ref(false);

const samplingRate = ref(100); //采样率
const intensity = ref(0); //烈度
const dataDelay = ref(0); //数据延迟

const options = {
  channelList: [
    {
      value: 'EIZ',
      label: 'EIZ-竖桥向',
      color: '#F16995',
    },
    {
      value: 'EIN',
      label: 'EIN-横桥向',
      color: '#77E3F9',
    },
    {
      value: 'EIE',
      label: 'EIE-纵桥向',
      color: '#DFC428',
    },
  ],
};

const channels = computed(() => {
  return options.channelList.map((cur, index) => {
    const { color, value } = cur;
    return {
      color,
      name: value,
      grid: {
        show: true,
        top: `15%`,
        left: `${33 * index + 3}%`,
        bottom: 0,
        width: '30%',
        height: '80%',
      },
    };
  });
});

let renderChart;
let updateChartConfig;
// 初始化渲染
const init = () => {
  const { renderChart: _renderChart, updateChartConfig: _updateChartConfig } =
    realDataChart({
      title: false,
      target: document.getElementById(uuid),
      channels: toRaw(channels.value),
    });
  renderChart = _renderChart;
  updateChartConfig = _updateChartConfig;
  if (props.stationId) connect();
};

const userStore = useUserStore();
// 格式化数据
const formatData = (cb) => {
  let data = {};
  const checkData = () => {
    let flag = false;
    if (Object.keys(data).length !== 3) return false;
    Object.values(data)
      .map((item) => item[0][0])
      .reduce((prev, cur) => {
        flag = prev === cur;
        return cur;
      });
    return flag;
  };
  const push = (_data) => {
    Object.keys(_data).forEach((_key) => {
      let key;
      switch (_key) {
        case 'Z':
          key = 'EIZ';
          break;
        case 'N':
          key = 'EIN';
          break;
        case 'E':
          key = 'EIE';
          break;
        default:
          break;
      }
      if (_key !== 'X') {
        data[key] = _data[_key];
        const element = data[key];
        dataDelay.value = element.at(-1)[0] - Date.now();
      } else {
        intensity.value = _data[_key];
      }
    });
    if (checkData()) {
      cb(data);
      data = {};
    }
  };
  return push;
};

const push = formatData((data) => {
  nextTick(() => {
    const box = document.querySelector('.wave_pic');
    box.style.background = 'transparent';
  });
  const dataSource = {};
  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      const element = data[key];
      dataSource[key] = element.reduce((prev, cur) => {
        if (cur[0] % 100 === 0) {
          prev.push(cur);
        }

        return prev;
      }, []);
    }
  }
  if (Object.keys(dataSource).length) {
    hasData.value = true;
  }
  renderChart(dataSource, intensity.value.toFixed(2));
});

const random = Math.random().toString().slice(-6);
const { connect, disconnect } = useEventSource(
  computed(() => `/api/edge/sse/300/${random}/${props.stationId}`),
  {
    headers: {
      ['Authorization']: `Bearer ${userStore.token}`,
      'Content-Type': 'application/json',
      Accept: '*/*',
    },
    withCredentials: false,
    onMessage(res) {
      const data = JSON.parse(res);
      push(data);
    },
    onError(error) {
      console.log(error);
      disconnect();
    },
  },
);

onMounted(() => {
  setTimeout(() => {
    init();
  }, 300);
});

watch(
  () => props.stationId,
  () => {
    intensity.value = 0;
    dataDelay.value = 0;
    hasData.value = false;
    disconnect();
    connect();
    updateChartConfig(
      toRaw(channels.value).map((cur, index) => {
        return {
          ...cur,
        };
      }),
    );
  },
  { deep: true },
);

onUnmounted(disconnect);
</script>

<style lang="scss" scoped>
.wave-wrap {
  position: absolute;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  width: 96%;
  height: 155px;
  padding: 16px 10px;
  margin-left: 50%;
  transform: translateX(-50%);
  background: url('/static/screen/structure-detail-bg.png') no-repeat;
  background-size: 100% 100%;
}

.item {
  display: flex;
  justify-content: space-between;
  padding: 0 30px;
  & > span {
    &:first-child {
      font-weight: 400;
      font-size: 14px;
      color: #c4e9ff;
      position: relative;
      margin-right: 40px;

      &::after {
        content: '';
        position: absolute;
        top: 4px;
        right: 0;
        width: 1px;
        height: 14px;
        background: #ffffff;
        opacity: 0.3;
        margin: 0 -30px;
      }
    }
    &:last-child {
      font-weight: 400;
      font-size: 14px;
      color: #ffffff;
    }
  }
}
// .wave_pic {
//   background: url('/static/bimface/empty.png') no-repeat center;
//   background-size: 50% 60%;
// }
</style>
